home *** CD-ROM | disk | FTP | other *** search
/ Aminet 51 / Aminet 51 (2002)(GTI - Schatztruhe)[!][Oct 2002].iso / Aminet / dev / c / TinyGL.lha / tinygl / src / zbuffer.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-08-25  |  11.1 KB  |  520 lines

  1. /*
  2.  
  3.  * Z buffer: 16 bits Z / 16 bits color
  4.  *
  5.  */
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <assert.h>
  9. #include <string.h>
  10. #include "zbuffer.h"
  11.  
  12. ZBuffer *ZB_open(int xsize, int ysize, int mode,
  13.                  int nb_colors,
  14.                  unsigned char *color_indexes,
  15.                  int *color_table,
  16.                  void *frame_buffer)
  17. {
  18.     ZBuffer *zb;
  19.     int size;
  20.  
  21.     zb = gl_malloc(sizeof(ZBuffer));
  22.     if (zb == NULL)
  23.         return NULL;
  24.  
  25.     zb->xsize = xsize;
  26.     zb->ysize = ysize;
  27.     zb->mode = mode;
  28.     zb->linesize = (xsize * PSZB + 3) & ~3;
  29.  
  30.     switch (mode) {
  31. #ifdef TGL_FEATURE_8_BITS
  32.     case ZB_MODE_INDEX:
  33.         ZB_initDither(zb, nb_colors, color_indexes, color_table);
  34.         break;
  35. #endif
  36. #ifdef TGL_FEATURE_32_BITS
  37.     case ZB_MODE_RGBA:
  38. #endif
  39. #ifdef TGL_FEATURE_24_BITS
  40.     case ZB_MODE_RGB24:
  41. #endif
  42.     case ZB_MODE_5R6G5B:
  43.         zb->nb_colors = 0;
  44.         break;
  45.     default:
  46.         goto error;
  47.     }
  48.  
  49.     size = zb->xsize * zb->ysize * sizeof(unsigned short);
  50.  
  51.     zb->zbuf = gl_malloc(size);
  52.     if (zb->zbuf == NULL)
  53.         goto error;
  54.  
  55.     if (frame_buffer == NULL) {
  56.         zb->pbuf = gl_malloc(zb->ysize * zb->linesize);
  57.         if (zb->pbuf == NULL) {
  58.             gl_free(zb->zbuf);
  59.             goto error;
  60.         }
  61.         zb->frame_buffer_allocated = 1;
  62.     } else {
  63.         zb->frame_buffer_allocated = 0;
  64.         zb->pbuf = frame_buffer;
  65.     }
  66.  
  67.     zb->current_texture = NULL;
  68.  
  69.     return zb;
  70.   error:
  71.     gl_free(zb);
  72.     return NULL;
  73. }
  74.  
  75. void ZB_close(ZBuffer * zb)
  76. {
  77. #ifdef TGL_FEATURE_8_BITS
  78.     if (zb->mode == ZB_MODE_INDEX)
  79.         ZB_closeDither(zb);
  80. #endif
  81.  
  82.     if (zb->frame_buffer_allocated)
  83.         gl_free(zb->pbuf);
  84.  
  85.     gl_free(zb->zbuf);
  86.     gl_free(zb);
  87. }
  88.  
  89. void ZB_resize(ZBuffer * zb, void *frame_buffer, int xsize, int ysize)
  90. {
  91.     int size;
  92.  
  93.     /* xsize must be a multiple of 4 */
  94.     xsize = xsize & ~3;
  95.  
  96.     zb->xsize = xsize;
  97.     zb->ysize = ysize;
  98.     zb->linesize = (xsize * PSZB + 3) & ~3;
  99.  
  100.     size = zb->xsize * zb->ysize * sizeof(unsigned short);
  101.  
  102.     gl_free(zb->zbuf);
  103.     zb->zbuf = gl_malloc(size);
  104.  
  105.     if (zb->frame_buffer_allocated)
  106.         gl_free(zb->pbuf);
  107.  
  108.     if (frame_buffer == NULL) {
  109.         zb->pbuf = gl_malloc(zb->ysize * zb->linesize);
  110.         zb->frame_buffer_allocated = 1;
  111.     } else {
  112.         zb->pbuf = frame_buffer;
  113.         zb->frame_buffer_allocated = 0;
  114.     }
  115. }
  116.  
  117. static void ZB_copyBuffer(ZBuffer * zb,
  118.                           void *buf,
  119.                           int linesize)
  120. {
  121.     unsigned char *p1;
  122.     PIXEL *q;
  123.     int y, n;
  124.  
  125.     q = zb->pbuf;
  126.     p1 = buf;
  127.     n = zb->xsize * PSZB;
  128.     for (y = 0; y < zb->ysize; y++) {
  129.         memcpy(p1, q, n);
  130.         p1 += linesize;
  131.         q = (PIXEL *) ((char *) q + zb->linesize);
  132.     }
  133. }
  134.  
  135. #if TGL_FEATURE_RENDER_BITS == 16
  136.  
  137. /* 32 bpp copy */
  138.  
  139. #ifdef TGL_FEATURE_32_BITS
  140.  
  141. #define RGB16_TO_RGB32(p0,p1,v)\
  142. {\
  143.     unsigned int g,b,gb;\
  144.     g = (v & 0x07E007E0) << 5;\
  145.     b = (v & 0x001F001F) << 3;\
  146.     gb = g | b;\
  147.     p0 = (gb & 0x0000FFFF) | ((v & 0x0000F800) << 8);\
  148.     p1 = (gb >> 16) | ((v & 0xF8000000) >> 8);\
  149. }
  150.  
  151. static void ZB_copyFrameBufferRGB32(ZBuffer * zb,
  152.                                     void *buf,
  153.                                     int linesize)
  154. {
  155.     unsigned short *q;
  156.     unsigned int *p, *p1, v, w0, w1;
  157.     int y, n;
  158.  
  159.     q = zb->pbuf;
  160.     p1 = (unsigned int *) buf;
  161.  
  162.     for (y = 0; y < zb->ysize; y++) {
  163.         p = p1;
  164.         n = zb->xsize >> 2;
  165.         do {
  166.             v = *(unsigned int *) q;
  167. #if BYTE_ORDER == BIG_ENDIAN
  168.             RGB16_TO_RGB32(w1, w0, v);
  169. #else
  170.             RGB16_TO_RGB32(w0, w1, v);
  171. #endif
  172.             p[0] = w0;
  173.             p[1] = w1;
  174.  
  175.             v = *(unsigned int *) (q + 2);
  176. #if BYTE_ORDER == BIG_ENDIAN
  177.             RGB16_TO_RGB32(w1, w0, v);
  178. #else
  179.             RGB16_TO_RGB32(w0, w1, v);
  180. #endif
  181.             p[2] = w0;
  182.             p[3] = w1;
  183.  
  184.             q += 4;
  185.             p += 4;
  186.         } while (--n > 0);
  187.  
  188.         p1 += linesize;
  189.     }
  190. }
  191.  
  192. #endif
  193.  
  194. /* 24 bit packed pixel handling */
  195.  
  196. #ifdef TGL_FEATURE_24_BITS
  197.  
  198. /* order: RGBR GBRG BRGB */
  199.  
  200. /* XXX: packed pixel 24 bit support not tested */
  201. /* XXX: big endian case not optimised */
  202.  
  203. #if BYTE_ORDER == BIG_ENDIAN
  204.  
  205. #define RGB16_TO_RGB24(p0,p1,p2,v1,v2)\
  206. {\
  207.     unsigned int r1,g1,b1,gb1,g2,b2,gb2;\
  208.     v1 = (v1 << 16) | (v1 >> 16);\
  209.     v2 = (v2 << 16) | (v2 >> 16);\
  210.     r1 = (v1 & 0xF800F800);\
  211.     g1 = (v1 & 0x07E007E0) << 5;\
  212.     b1 = (v1 & 0x001F001F) << 3;\
  213.     gb1 = g1 | b1;\
  214.     p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24);\
  215.     g2 = (v2 & 0x07E007E0) << 5;\
  216.     b2 = (v2 & 0x001F001F) << 3;\
  217.     gb2 = g2 | b2;\
  218.     p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff);\
  219.     p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16);\
  220. }
  221.  
  222. #else
  223.  
  224. #define RGB16_TO_RGB24(p0,p1,p2,v1,v2)\
  225. {\
  226.     unsigned int r1,g1,b1,gb1,g2,b2,gb2;\
  227.     r1 = (v1 & 0xF800F800);\
  228.     g1 = (v1 & 0x07E007E0) << 5;\
  229.     b1 = (v1 & 0x001F001F) << 3;\
  230.     gb1 = g1 | b1;\
  231.     p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24);\
  232.     g2 = (v2 & 0x07E007E0) << 5;\
  233.     b2 = (v2 & 0x001F001F) << 3;\
  234.     gb2 = g2 | b2;\
  235.     p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff);\
  236.     p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16);\
  237. }
  238.  
  239. #endif
  240.  
  241. static void ZB_copyFrameBufferRGB24(ZBuffer * zb,
  242.                                     void *buf,
  243.                                     int linesize)
  244. {
  245.     unsigned short *q;
  246.     unsigned int *p, *p1, w0, w1, w2, v0, v1;
  247.     int y, n;
  248.  
  249.     q = zb->pbuf;
  250.     p1 = (unsigned int *) buf;
  251.     linesize = linesize * 3;
  252.  
  253.     for (y = 0; y < zb->ysize; y++) {
  254.         p = p1;
  255.         n = zb->xsize >> 2;
  256.         do {
  257.             v0 = *(unsigned int *) q;
  258.             v1 = *(unsigned int *) (q + 2);
  259.             RGB16_TO_RGB24(w0, w1, w2, v0, v1);
  260.             p[0] = w0;
  261.             p[1] = w1;
  262.             p[2] = w2;
  263.  
  264.             q += 4;
  265.             p += 3;
  266.         } while (--n > 0);
  267.  
  268.         /* ((char *) p1) += linesize;*/
  269.         p1=(unsigned int *)&((char *)p1)[linesize];
  270.     }
  271. }
  272.  
  273. #endif
  274.  
  275. void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
  276.                         int linesize)
  277. {
  278.     switch (zb->mode) {
  279. #ifdef TGL_FEATURE_8_BITS
  280.     case ZB_MODE_INDEX:
  281.         ZB_ditherFrameBuffer(zb, buf, linesize >> 1);
  282.         break;
  283. #endif
  284. #ifdef TGL_FEATURE_16_BITS
  285.     case ZB_MODE_5R6G5B:
  286.         ZB_copyBuffer(zb, buf, linesize);
  287.         break;
  288. #endif
  289. #ifdef TGL_FEATURE_32_BITS
  290.     case ZB_MODE_RGBA:
  291.         ZB_copyFrameBufferRGB32(zb, buf, linesize >> 1);
  292.         break;
  293. #endif
  294. #ifdef TGL_FEATURE_24_BITS
  295.     case ZB_MODE_RGB24:
  296.         ZB_copyFrameBufferRGB24(zb, buf, linesize >> 1);
  297.         break;
  298. #endif
  299.     default:
  300.         assert(0);
  301.     }
  302. }
  303.  
  304. #endif /* TGL_FEATURE_RENDER_BITS == 16 */
  305.  
  306. #if TGL_FEATURE_RENDER_BITS == 24
  307.  
  308. #define RGB24_TO_RGB16(r, g, b) \
  309.   ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
  310.  
  311. /* XXX: not optimized */
  312. static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb,
  313.                                      void *buf, int linesize)
  314. {
  315.     PIXEL *q;
  316.     unsigned short *p, *p1;
  317.     int y, n;
  318.  
  319.     q = zb->pbuf;
  320.     p1 = (unsigned short *) buf;
  321.  
  322.     for (y = 0; y < zb->ysize; y++) {
  323.         p = p1;
  324.         n = zb->xsize >> 2;
  325.         do {
  326.             p[0] = RGB24_TO_RGB16(q[0], q[1], q[2]);
  327.             p[1] = RGB24_TO_RGB16(q[3], q[4], q[5]);
  328.             p[2] = RGB24_TO_RGB16(q[6], q[7], q[8]);
  329.             p[3] = RGB24_TO_RGB16(q[9], q[10], q[11]);
  330.             q = (PIXEL *)((char *)q + 4 * PSZB);
  331.             p += 4;
  332.         } while (--n > 0);
  333.         p1 = (unsigned short *)((char *)p1 + linesize);
  334.     }
  335. }
  336.  
  337. void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
  338.                         int linesize)
  339. {
  340.     switch (zb->mode) {
  341. #ifdef TGL_FEATURE_16_BITS
  342.     case ZB_MODE_5R6G5B:
  343.         ZB_copyFrameBuffer5R6G5B(zb, buf, linesize);
  344.         break;
  345. #endif
  346. #ifdef TGL_FEATURE_24_BITS
  347.     case ZB_MODE_RGB24:
  348.         ZB_copyBuffer(zb, buf, linesize);
  349.         break;
  350. #endif
  351.     default:
  352.         assert(0);
  353.     }
  354. }
  355.  
  356. #endif /* TGL_FEATURE_RENDER_BITS == 24 */
  357.  
  358. #if TGL_FEATURE_RENDER_BITS == 32
  359.  
  360. #define RGB32_TO_RGB16(v) \
  361.   (((v >> 8) & 0xf800) | (((v) >> 5) & 0x07e0) | (((v) & 0xff) >> 3))
  362.  
  363. /* XXX: not optimized */
  364. static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb,
  365.                                      void *buf, int linesize)
  366. {
  367.     PIXEL *q;
  368.     unsigned short *p, *p1;
  369.     int y, n;
  370.  
  371.     q = zb->pbuf;
  372.     p1 = (unsigned short *) buf;
  373.  
  374.     for (y = 0; y < zb->ysize; y++) {
  375.         p = p1;
  376.         n = zb->xsize >> 2;
  377.         do {
  378.             p[0] = RGB32_TO_RGB16(q[0]);
  379.             p[1] = RGB32_TO_RGB16(q[1]);
  380.             p[2] = RGB32_TO_RGB16(q[2]);
  381.             p[3] = RGB32_TO_RGB16(q[3]);
  382.             q += 4;
  383.             p += 4;
  384.         } while (--n > 0);
  385.         p1 = (unsigned short *)((char *)p1 + linesize);
  386.     }
  387. }
  388.  
  389. void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
  390.                         int linesize)
  391. {
  392.     switch (zb->mode) {
  393. #ifdef TGL_FEATURE_16_BITS
  394.     case ZB_MODE_5R6G5B:
  395.         ZB_copyFrameBuffer5R6G5B(zb, buf, linesize);
  396.         break;
  397. #endif
  398. #ifdef TGL_FEATURE_32_BITS
  399.     case ZB_MODE_RGBA:
  400.         ZB_copyBuffer(zb, buf, linesize);
  401.         break;
  402. #endif
  403.     default:
  404.         assert(0);
  405.     }
  406. }
  407.  
  408. #endif /* TGL_FEATURE_RENDER_BITS == 32 */
  409.  
  410.  
  411. /*
  412.  * adr must be aligned on an 'int'
  413.  */
  414. void memset_s(void *adr, int val, int count)
  415. {
  416.     int i, n, v;
  417.     unsigned int *p;
  418.     unsigned short *q;
  419.  
  420.     p = adr;
  421.     v = val | (val << 16);
  422.  
  423.     n = count >> 3;
  424.     for (i = 0; i < n; i++) {
  425.         p[0] = v;
  426.         p[1] = v;
  427.         p[2] = v;
  428.         p[3] = v;
  429.         p += 4;
  430.     }
  431.  
  432.     q = (unsigned short *) p;
  433.     n = count & 7;
  434.     for (i = 0; i < n; i++)
  435.         *q++ = val;
  436. }
  437.  
  438. void memset_l(void *adr, int val, int count)
  439. {
  440.     int i, n, v;
  441.     unsigned int *p;
  442.  
  443.     p = adr;
  444.     v = val;
  445.     n = count >> 2;
  446.     for (i = 0; i < n; i++) {
  447.         p[0] = v;
  448.         p[1] = v;
  449.         p[2] = v;
  450.         p[3] = v;
  451.         p += 4;
  452.     }
  453.  
  454.     n = count & 3;
  455.     for (i = 0; i < n; i++)
  456.         *p++ = val;
  457. }
  458.  
  459. /* count must be a multiple of 4 and >= 4 */
  460. void memset_RGB24(void *adr,int r, int v, int b,long count)
  461. {
  462.     long i, n;
  463.     register long v1,v2,v3,*pt=(long *)(adr);
  464.     unsigned char *p,R=(unsigned char)r,V=(unsigned char)v,B=(unsigned char)b;
  465.  
  466.     p=(unsigned char *)adr;
  467.     *p++=R;
  468.     *p++=V;
  469.     *p++=B;
  470.     *p++=R;
  471.     *p++=V;
  472.     *p++=B;
  473.     *p++=R;
  474.     *p++=V;
  475.     *p++=B;
  476.     *p++=R;
  477.     *p++=V;
  478.     *p++=B;
  479.     v1=*pt++;
  480.     v2=*pt++;
  481.     v3=*pt++;
  482.     n = count >> 2;
  483.     for(i=1;i<n;i++) {
  484.         *pt++=v1;
  485.         *pt++=v2;
  486.         *pt++=v3;
  487.     }
  488. }
  489.  
  490. void ZB_clear(ZBuffer * zb, int clear_z, int z,
  491.               int clear_color, int r, int g, int b)
  492. {
  493. #if TGL_FEATURE_RENDER_BITS != 24
  494.     int color;
  495. #endif
  496.     int y;
  497.     PIXEL *pp;
  498.  
  499.     if (clear_z) {
  500.         memset_s(zb->zbuf, z, zb->xsize * zb->ysize);
  501.     }
  502.     if (clear_color) {
  503.         pp = zb->pbuf;
  504.         for (y = 0; y < zb->ysize; y++) {
  505. #if TGL_FEATURE_RENDER_BITS == 15 || TGL_FEATURE_RENDER_BITS == 16
  506.             color = RGB_TO_PIXEL(r, g, b);
  507.             memset_s(pp, color, zb->xsize);
  508. #elif TGL_FEATURE_RENDER_BITS == 32
  509.             color = RGB_TO_PIXEL(r, g, b);
  510.             memset_l(pp, color, zb->xsize);
  511. #elif TGL_FEATURE_RENDER_BITS == 24
  512.             memset_RGB24(pp,r>>8,g>>8,b>>8,zb->xsize);
  513. #else
  514. #error TODO
  515. #endif
  516.             pp = (PIXEL *) ((char *) pp + zb->linesize);
  517.         }
  518.     }
  519. }
  520.